﻿using System;
using System.Diagnostics;
using System.Net;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Nablasoft.Console.Utils;
using TfsUtils.Utils;
using System.Linq;

namespace TfsUtils.Commands
{
    public class QueryDuplicator : BaseCommand
    {

        internal override int OnExecute()
        {
            TfsTeamProjectCollection tfs = CreateTfsTeamProjectCollection();

           
            var ss = tfs.GetService<ICommonStructureService>();
            //ProjectInfo teamProject= ss.GetProjectFromName(projectName);

            WorkItemStore store = tfs.GetService<WorkItemStore>();
            //Project project = store.Projects[projectName];

            string iterationsource = GetParameterValue<String>("iterationsource");
            string iterationdest = GetParameterValue<String>("iterationdest");
            string projectName = GetParameterValue<String>("teamproject");
            SendMessage(string.Format("Copy query from iteration {0} to {1} for project {2}", iterationsource, iterationdest, projectName));

            QueryHierarchy queryHierarchy = store.Projects[projectName].QueryHierarchy;
            var qj = Search(queryHierarchy, iterationsource);
            
            var qd = Search(queryHierarchy, iterationdest);
            Duplicate(qj, qd, iterationsource, iterationdest);
            queryHierarchy.Save();
            return 0;
        }

        private QueryFolder Search(QueryHierarchy hierarchy, String name)
        {
            SendDebug("Searching folder:" + hierarchy.Path);
             foreach (QueryFolder queryFolder in hierarchy)
             {
                 var result = Search(queryFolder, name);
                 if (result != null) return result;
             }
             return null;
         }

        private QueryFolder Search(QueryFolder hierarchy, String name)
        {

            foreach (QueryItem queryFolder in hierarchy)
            {
                SendDebug("Searching folder:" + queryFolder.Path);
                QueryFolder folder = queryFolder as QueryFolder;
                if (folder == null) continue;
                if (name.Equals(folder.Name, StringComparison.OrdinalIgnoreCase))
                {
                    SendDebug("Found folder:" + queryFolder.Path);
                    return folder;
                }

                var result = Search(folder, name);
                if (result != null) 
                    return result;
            }
            return null;
        }

        private void Duplicate(QueryFolder qj, QueryFolder qd, string iterationsource, string iterationdest)
        {
            foreach (QueryItem item in qj)
            {
                if (qd.Contains(item.Name))
                {
                    SendWarn("Skipping " + item.Name + " because it already exists on destination folder.");
                    continue;
                }

                if (item is QueryFolder)
                {
                    QueryFolder queryFolder = new QueryFolder(item.Name);
                    qd.Add(queryFolder);
                    SendInfo("Duplicate folder" + item.Path + " to " + qd.Path);
                    Duplicate(item as QueryFolder, queryFolder, iterationsource, iterationdest);
                }
                else if (item is QueryDefinition)
                {

                    QueryDefinition def = item as QueryDefinition;
                    string queryText = def.QueryText.Replace(iterationsource, iterationdest);
                    SendInfo("Duplicate definition" + item.Path + " to " + qd.Path);
                    QueryDefinition queryDefinition = new QueryDefinition(def.Name, queryText); 
                    qd.Add(queryDefinition);
                }
            }
            
        }
    }
}
